import type { RouteLocationNormalized, NavigationGuardNext, Router } from "vue-router";
import { useUserStoreHook } from "@/stores/modules/user";
import { usePermissionStoreHook } from "@/stores/modules/permission";
import { Constant } from "@/constant";
import { wechatApi } from "@/api/wechat/index";
import { storageUtil } from "@/utils/storage";

import NProgress from "nprogress";
import "nprogress/nprogress.css";

NProgress.configure({ showSpinner: false }); // 进度条

// 白名单路由
const whiteList = [
  "/login",
  "/wechat/slilogin",
  "/wechat/register",
  "/alipay/alilogin",
  "/unionpay/login"
];

export function addRoutePerm(router: Router) {
  const permissionStore = usePermissionStoreHook();
  router.beforeEach(
    async (
      to: RouteLocationNormalized,
      from: RouteLocationNormalized,
      next: NavigationGuardNext
    ) => {
      NProgress.start();
      const userStore = useUserStoreHook();
      const expire = userStore.isTokenExpires();
      const tenant = userStore.user.tenant;
      if (userStore.token && !expire) {
        if (to.path === "/login") {
          // 如果已登录，跳转首页
          next({ path: "/", query: { tenant: tenant } });
          NProgress.done();
        } else {
          const hasRoles = userStore.user.roleCodes && userStore.user.roleCodes.length > 0;
          if (hasRoles) {
            // 未匹配到任何路由，跳转404
            if (to.matched.length === 0 && from.name) {
              next({ name: from.name, query: { tenant: tenant } });
            } else if (to.matched.length === 0) {
              next({ path: "/404", query: { tenant: tenant } });
            } else if (to.query.tenant) {
              next();
            } else {
              to.query.tenant = tenant;
              next({
                ...to
              });
            }
          } else {
            try {
              const rolesPerms = await userStore.getRoleInfo();
              await userStore.getUserInfo();
              const accessRoutes = await permissionStore.generateRoutes(rolesPerms);
              accessRoutes.forEach((route: any) => {
                router.addRoute(route);
              });
              next();
            } catch (error) {
              // 移除 token 并跳转登录页
              await userStore.clearToken();
              toLogin(tenant, to, from, next);
              NProgress.done();
            }
          }
        }
      } else {
        //清理Token.
        userStore.clearToken();
        // 未登录可以访问白名单页面
        if (validWhileList(to.path) && to.query.tenant) {
          if (storageUtil.hasCode(to.query.code as string) && to.path.indexOf("slilogin") > -1) {
            authUrl(to);
            return;
          }
          next();
        } else if (validWhileList(to.path)) {
          to.query.tenant = tenant;
          next({
            ...to,
            replace: true
          });
        } else {
          toLogin(tenant, to, from, next);
          NProgress.done();
        }
      }
    }
  );

  router.afterEach(() => {
    NProgress.done();
  });
}

/**判断是否在白名单内. */
function validWhileList(path: string) {
  // 改写后的代码
  const result = whiteList.some((white) => {
    const startsWithResult = path.startsWith(white);
    return startsWithResult;
  });

  return result;
}

function authUrl(to: RouteLocationNormalized) {
  const url = window.location.href.slice(0, -to.fullPath.length);

  storageUtil.setRedirect(to);
  wechatApi
    .authUrl({
      redirectUri: url + "/wechat/slilogin",
      state: "123" //route.query.code as string
    })
    .then((res) => {
      window.location.href = res.data;
    });
}

function toLogin(
  tenant: string,
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext
) {
  if (Constant.IS_WECHAT) {
    authUrl(to);
  } else if (Constant.IS_ALIPAY) {
    next({
      path: `/alipay/alilogin`,
      query: { tenant: tenant, redirect: to.fullPath }
    });
  } else if (Constant.IS_UNIONPAY) {
    next({
      path: `/unionpay/login`,
      query: { tenant: tenant, redirect: to.fullPath }
    });
  } else {
    next({
      path: `/login`,
      query: { tenant: tenant, redirect: to.fullPath }
    });
  }
}
